package com.yy.job.facade;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.yy.job.common.enums.JobExecuteTypeEnum;
import com.yy.job.core.config.JobConfigXmlContext;
import com.yy.job.core.domain.JobDomain;
import com.yy.job.core.run.JobApplicationStartListener;
import com.yy.job.core.run.worker.ModuleWorker;
import com.yy.job.facade.converter.YYJobModelConverter;
import com.yy.job.facade.model.YYJobModel;
import com.yy.job.facade.validator.YYJobModelValidator;
import com.yy.job.service.IJobManager;

/**
 * yy-job提交入口
 * 
 * @author eleven.li
 *
 */
@Service
public class JobFacade {

	private Logger log = LoggerFactory.getLogger(JobFacade.class);

	@Resource
	private JobConfigXmlContext jobConfigParser;

	@Resource
	private IJobManager iJobManager;

	@Resource
	private JobApplicationStartListener jobBossStartListener;

	@Autowired
	private YYJobModelValidator jobModelValidator;
	
	@Autowired
	private YYJobModelConverter jobModelConverter;
	
	/**
	 * 提交入口<br>
	 * 
	 * @param yyJobModel
	 * @return
	 * @throws Exception
	 */
	public Long submitJob(YYJobModel yyJobModel) {
		log.info("JobFacade submit new job, yyJobModel={}", JSON.toJSONString(yyJobModel));
		
		// 校验合法性
		this.jobModelValidator.validate(yyJobModel);
		// 组装job模型数据
		JobDomain job = jobModelConverter.convertToDomain(yyJobModel);
		// 保存job和job_step表数据
		Long jobId = this.iJobManager.submit(job);
		
		// 高优先级需要马上启动的任务，直接插队唤起线程启动
		if(JobExecuteTypeEnum.PRIORITY.equals(yyJobModel.getJobExecuteType())) {
			job.setId(jobId);
			ModuleWorker jobBoss = (ModuleWorker) this.jobBossStartListener.getModulWorkerMap().get(job.getModuleCode());
			
			// 立即执行
			jobBoss.executePriorityJob(job);
		}
		// 立即锁定并进入本机的执行队列，分布式下方便测试
		else if(JobExecuteTypeEnum.LOCAL.equals(yyJobModel.getJobExecuteType())) {
			job.setId(jobId);
			ModuleWorker jobBoss = (ModuleWorker) this.jobBossStartListener.getModulWorkerMap().get(job.getModuleCode());
			jobBoss.getLocalJobQueue().add(job);
		}
		
		return jobId;
	}

}
